import { getDateAll } from './../utils'
export default {
  props: {
    info: {
      type: Object
    },
    model: {
      type: Object
    },
    size: {
      type: String
    },
    value: {
      type: [String, Number, Array, Object, Date, Function]
    },
    operateType: {
      type: String
    },
    // 客户正在操作的子组件键值项
    activeItem: {
      type: Object
    }
  },
  computed: {
    type () {
      // String 传入的label值
      let { type = 'text' } = this.info
      return type
    },
    text () {
      // String 传入的label值
      let { label: text } = this.info
      return text
    },
    label () {
      // String 表单元素的label值
      let { label: text } = this.info
      return text && `${text}：`
    },
    keyName () {
      // String key值
      return this.info.key
    },
    prop () {
      // String key值
      return this.info.key
    },
    labelWidth () {
      // Number 表单元素的label宽度
      return this.info.labelWidth
    },
    rules () {
      let {
        pattern,
        rules,
        label,
        type = 'text',
        daterange // 日期选择组件使用范围（格式：[1, 100]，单位：天）
      } = this.info
      let qingxuanze = [
        'radio',
        'select',
        'checkbox',
        'date',
        'daterange',
        'datetime',
        'datetimerange',
        'year',
        'month'
      ].includes(type)
        ? '请选择'
        : ['upload'].includes(type)
          ? '请上传'
          : '请输入'
      const typeMap = {
        checkbox: 'array',
        daterange: 'array',
        datetimerange: 'array'
      }
      const valueType = typeMap[type]
      let _rules = [{
        required: true,
        message: `${qingxuanze}${label}`,
        trigger: 'blur',
        [valueType && 'type']: valueType
      }]
      if (pattern) {
        _rules.push({
          message: `${qingxuanze}正确${label}`,
          pattern,
          trigger: 'blur'
        })
      } else if ('daterange,datetimerange'.includes(type)) {
        _rules.splice(1, 0, ...[{
          message: `${qingxuanze}${label}`,
          pattern: /^\[.*\d.*\]$/,
          transform: _v => {
            return _v ? JSON.stringify(_v) : _v
          }
        }])
        if (daterange) {
          const [min, max] = daterange
          _rules.splice(2, 0, ...[{
            message: `${label}的范围不能小于${min}天`,
            pattern: /^\[.*\d.*\]$/,
            transform: _v => {
              const params = typeof _v === 'string' ? JSON.parse(_v) : _v
              const dates = getDateAll(params)
              const { length } = dates
              if (length < min) {
                return '["",""]'
              }
              return _v
            }
          }, {
            message: `${label}的范围不能大于${max}天`,
            pattern: /^\[.*\d.*\]$/,
            transform: _v => {
              const params = typeof _v === 'string' ? JSON.parse(_v) : _v
              const dates = getDateAll(params)
              const { length } = dates
              if (length > max) {
                return '["",""]'
              }
              return _v
            }
          }])
        }
      }
      return Array.isArray(rules) ? rules : (rules === true || pattern) ? _rules : []
    },
    // Array 用于select、radio、文本显示等（list不再用计算属性，改为data赋值）
    // list () {},
    callback () {
      // 如果有list的时候 可以设置一个回调函数 点击list中的item 返回fn(item)
      let { callback = e => e } = this.info
      return callback
    },
    loading () {
      // 当前是否正在远程搜索 input和select组件会用到
      let { loading = true } = this.info
      return loading
    },
    disabled () {
      // 禁用
      let { disabled = false } = this.info
      return disabled
    },
    placeholder () {
      // Sring 暗纹
      let { placeholder } = this.info
      return this.operateType === 'view' ? ' ' : placeholder
    },
    clearable () {
      let { clearable = false } = this.info
      return clearable
    },
    // 4.0.0 在 type="password" 时，开启属性 password 可以切换显示隐藏密码（icon）
    password () {
      let { password = false } = this.info
      return password
    },
    // 类似password，引入的是图片（image）
    eyes () {
      let { eyes = false } = this.info
      return eyes
    }
  },
  data () {
    const setCurrentValue = (value, type = 'text') => {
      const defaultMap = {
        select: [],
        checkbox: [],
        daterange: [],
        datetimerange: []
      }
      let _value = defaultMap[type] || ''
      return typeof value === 'function' ? _value : value
    }
    return {
      currentValue: setCurrentValue(this.value, this.info.type),
      list: [],
      listItem: {}
    }
  },
  created () {
    this.info.list && this._setList()
  },
  watch: {
    currentValue (_v) {
      // 设置客户正在操作的子组件键值项
      this.$emit('setActiveItem', { key: this.keyName, value: _v })
      // 提供v-model
      this.$emit('input', _v)
      console.log(_v)
    },
    model: {
      handler (v) {
        this.callback({
          vm: this,
          param: v,
          key: this.keyName,
          currentKey: this.keyName,
          currentValue: this.currentValue,
          activeKey: this.activeItem.key,
          activeValue: this.activeItem.value,
          listItem: this.listItem,
          注释: `
            每当参数有变动时，infos所有子项都会执行callback函数，返回内容如下：
            1. vm是子组件this
            2. param是表单参数
            3. currentkey是回调函数所在子组件key名
            4. currentValue是回调函数所在子组件value值
            5. activeKey是客户正在操作的子组件key名
            6. activeValue是客户正在操作的子组件value值
            7. listItem是list选中项内容
          `
        })
      },
      deep: true
    }
  },
  methods: {
    async _setValue (_li) {
      let _v = this.value
      if (typeof _v === 'function') {
        this.currentValue = await _v(_li, this.info)
      }
    },
    async _setList () {
      let _li = this.info.list
      let _param = this.currentValue
      if (typeof _li === 'function') {
        _li = await _li(_param)
        if (!Array.isArray(_li)) {
          throw Error(`${this.info.key}子项中的list属性方法返回值必须为数组...`)
        }
      }
      // 回显时对checkbox、radio、select操作
      if (this.operateType === 'view') {
        _li = _li.filter(o =>
          Array.isArray(this.value)
            ? this.value.includes(o.value)
            : this.value === o.value
        )
      }
      this.list = _li
      // 处理玩list之后，判断value是否为函数形式
      this._setValue(_li)
    }
  }
}
